<template>
  <view class="transaction-page">
    <!-- 自定义导航栏 -->
    <CustomNavbar title="记一笔"></CustomNavbar>
    
    <!-- 分段器：支出/收入 -->
    <view class="segment-container">
      <view 
        class="segment-item" 
        :class="{ active: activeTab === 'expense' }" 
        @click="switchTab('expense')"
      >
        支出
      </view>
      <view 
        class="segment-item" 
        :class="{ active: activeTab === 'income' }" 
        @click="switchTab('income')"
      >
        收入
      </view>
    </view>
    
    <!-- 分类选择区域 -->
    <swiper class="category-swiper" :current="swiperCurrent" @change="onSwiperChange">
      <!-- 支出分类 -->
      <swiper-item>
        <scroll-view scroll-y class="category-scroll" @scrolltolower="loadMoreCategories">
          <view class="category-list" v-if="!loading">
            <view 
              v-for="(item, index) in categoryList" 
              :key="item.id" 
              class="category-item"
              :class="{ active: selectedCategory.id === item.id }"
              @click="selectCategory(item)"
            >
              <view class="category-icon" :style="{ backgroundColor: item.color + '20' }">
                <image :src="item.icon || '/static/images/default-category.png'" mode="aspectFit"></image>
              </view>
              <text class="category-name">{{ item.name }}</text>
            </view>
          </view>
          <view v-else class="loading-container">
            <uni-icons type="spinner-cycle" size="30" color="#999"></uni-icons>
            <text class="loading-text">加载中...</text>
          </view>
          
          <!-- 加载更多 -->
          <uni-load-more :status="loadMoreStatus" v-if="categoryList.length > 0"></uni-load-more>
        </scroll-view>
      </swiper-item>
      
      <!-- 收入分类 -->
      <swiper-item>
        <scroll-view scroll-y class="category-scroll" @scrolltolower="loadMoreCategories">
          <view class="category-list" v-if="!loading">
            <view 
              v-for="(item, index) in categoryList" 
              :key="item.id" 
              class="category-item"
              :class="{ active: selectedCategory.id === item.id }"
              @click="selectCategory(item)"
            >
              <view class="category-icon" :style="{ backgroundColor: item.color + '20' }">
                <image :src="item.icon || '/static/images/default-category.png'" mode="aspectFit"></image>
              </view>
              <text class="category-name">{{ item.name }}</text>
            </view>
          </view>
          <view v-else class="loading-container">
            <uni-icons type="spinner-cycle" size="30" color="#999"></uni-icons>
            <text class="loading-text">加载中...</text>
          </view>
          
          <!-- 加载更多 -->
          <uni-load-more :status="loadMoreStatus" v-if="categoryList.length > 0"></uni-load-more>
        </scroll-view>
      </swiper-item>
    </swiper>
    
    <!-- 键盘顶部区域 -->
    <view class="keyboard-header">
      <!-- 平台选择 -->
      <view class="platform-selector" @click="showPlatformSelector">
        <image :src="selectedPlatform.icon || '/static/images/default-platform.png'" mode="aspectFit"></image>
      </view>
      
      <!-- 输入信息区域 -->
      <view class="input-area">
        <!-- 备注输入 -->
        <view class="remark-input">
          <input type="text" v-model="formData.remark" placeholder="添加备注..." />
        </view>
        
        <!-- 金额显示和图片上传 -->
        <view class="amount-upload">
          <view class="amount-display">{{ displayAmount }}</view>
          <view class="upload-btn" @click.stop="handleImageAction">
            <view class="image-badge" v-if="imageList.length > 0">{{ imageList.length }}</view>
            <image src="/static/images/upload.png" mode="aspectFit"></image>
          </view>
        </view>
      </view>
    </view>
    
    <!-- 自定义键盘 -->
    <view class="custom-keyboard">
      <!-- 数字键盘区域 -->
      <view class="number-keys">
        <view class="key-row">
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('7')">7</button>
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('8')">8</button>
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('9')">9</button>
        </view>
        <view class="key-row">
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('4')">4</button>
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('5')">5</button>
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('6')">6</button>
        </view>
        <view class="key-row">
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('1')">1</button>
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('2')">2</button>
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('3')">3</button>
        </view>
        <view class="key-row">
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('.')">.</button>
          <button class="key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('0')">0</button>
          <button class="key delete-key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="deleteKey">
            <uni-icons type="closeempty" size="18" color="#333"></uni-icons>
          </button>
        </view>
      </view>
      
      <!-- 功能键区域 -->
      <view class="function-keys">
        <button class="key date-key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @click.stop.prevent="showDatePicker">
          <text>{{ formatDate(formData.transactionDate) }}</text>
        </button>
        <button class="key operator-key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('+')">
          <uni-icons type="plusempty" size="25" color="#ff6b6b"></uni-icons>
        </button>
        <button class="key operator-key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="inputKey('-')">—</button>
        <button class="key submit-key" hover-class="key-hover" hover-start-time="0" hover-stay-time="50" @touchstart.stop.prevent="submitTransaction">完成</button>
      </view>
    </view>
    
    <!-- 平台选择弹窗 -->
    <uni-popup ref="platformPopup" type="bottom">
      <view class="popup-content">
        <view class="popup-header">
          <text>选择平台</text>
          <view class="close-btn" @click="closePlatformPopup">
            <uni-icons type="close" size="20" color="#999"></uni-icons>
          </view>
        </view>
        <scroll-view scroll-y class="platform-scroll">
          <view class="platform-list">
            <view 
              v-for="(item, index) in platforms" 
              :key="item.id" 
              class="platform-item"
              :class="{ active: selectedPlatform.id === item.id }"
              @click="selectPlatform(item)"
            >
              <view class="platform-icon">
                <image :src="item.icon || '/static/images/default-platform.png'" mode="aspectFit"></image>
              </view>
              <text class="platform-name">{{ item.name }}</text>
            </view>
          </view>
        </scroll-view>
      </view>
    </uni-popup>
    
    <!-- 日期时间选择器弹窗 -->
    <uni-popup ref="datePopup" type="bottom">
      <view class="popup-content date-picker-popup" @touchmove.stop.prevent>
        <view class="popup-header">
          <text>选择日期和时间</text>
          <view class="close-btn" @click="onDateTimeCancel">
            <uni-icons type="close" size="20" color="#999"></uni-icons>
          </view>
        </view>
        <view class="picker-container" @touchmove.stop.prevent>
          <picker-view 
            :value="datePickerValue" 
            class="picker-view" 
            @change="onDatePickerChange"
            indicator-style="height: 40px;"
            mask-style="background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.9));"
            @touchmove.stop.prevent
          >
            <picker-view-column>
              <view class="picker-item" v-for="(year, index) in years" :key="index">{{ year }}</view>
            </picker-view-column>
            <picker-view-column>
              <view class="picker-item" v-for="(month, index) in months" :key="index">{{ month }}</view>
            </picker-view-column>
            <picker-view-column>
              <view class="picker-item" v-for="(day, index) in days" :key="index">{{ day }}</view>
            </picker-view-column>
            <picker-view-column>
              <view class="picker-item" v-for="(hour, index) in hours" :key="index">{{ hour }}</view>
            </picker-view-column>
            <picker-view-column>
              <view class="picker-item" v-for="(minute, index) in minutes" :key="index">{{ minute }}</view>
            </picker-view-column>
          </picker-view>
        </view>
        <view class="popup-footer">
          <button class="confirm-btn" @click.stop.prevent="onDateTimeConfirm">确认</button>
        </view>
      </view>
    </uni-popup>

    <!-- 图片预览和管理页面 -->
    <uni-popup ref="imageManagerPopup" type="center" @touchmove.stop.prevent>
      <view class="image-manager-container" @touchmove.stop.prevent>
        <view class="popup-header">
          <text>凭证管理</text>
          <view class="close-btn" @click="closeImageManager">
            <uni-icons type="close" size="20" color="#999"></uni-icons>
          </view>
        </view>
        <scroll-view scroll-y class="image-list-scroll">
          <view class="image-list">
            <view 
              v-for="(item, index) in imageList" 
              :key="index" 
              class="image-item"
              @longpress="showDeleteConfirm(index)"
              @click="previewImage(index)"
            >
              <image :src="item.path" mode="aspectFill"></image>
              <view class="image-status" v-if="item.compressing">
                <text class="status-text">压缩中...</text>
              </view>
              <view class="image-info" v-if="!item.compressing && item.compressionRatio > 0">
                <text class="info-text">-{{ item.compressionRatio }}%</text>
              </view>
              <view class="image-error" v-if="item.compressionError">
                <text class="error-text">压缩失败</text>
              </view>
            </view>
            <view class="image-item add-image" @click="chooseImage" v-if="imageList.length < 9">
              <uni-icons type="plusempty" size="40" color="#CCCCCC"></uni-icons>
            </view>
          </view>
        </scroll-view>
        <view class="image-stats" v-if="imageList.length > 0">
          <text class="stats-text">共{{ imageList.length }}张图片，{{ getTotalCompressionInfo() }}</text>
        </view>
        <view class="popup-footer">
          <button class="confirm-btn" @click="closeImageManager">确认</button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>

<script setup>
import { ref, computed, onMounted, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { queryCategories } from '@/api/category.js';
import { queryPlatforms } from '@/api/platform.js';
import { addTransaction, updateTransaction, queryTransactions, updateTransactionReceipt } from '@/api/transaction.js';
// 移除lrz库引用
// import lrz from 'lrz';

// 当前激活的标签页：支出/收入
const activeTab = ref('expense');
const swiperCurrent = ref(0);

// 分类数据
const categoryList = ref([]);
const loading = ref(true);
const loadMoreStatus = ref('more'); // 加载状态：more, loading, noMore

// 平台数据
const platforms = ref([]);

// 表单数据
const formData = reactive({
  categoryId: null,
  platformId: null,
  amount: '',
  transactionDate: new Date(),
  remark: '',
  // 支出为0，收入为1
  type: 0,
});

// 日期选择器相关
const datePopup = ref(null);
const datePickerValue = ref([0, 0, 0, 0, 0]);
const years = ref([]);
const months = ref([]);
const days = ref([]);
const hours = ref([]);
const minutes = ref([]);
// 保存上次选择的时间，用于连续添加账单
const lastSelectedDate = ref(new Date());

// 搜索表单
let page = ref(1);
const pageSize = 20;

// 选中的分类和平台
const selectedCategory = ref({});
const selectedPlatform = ref({});

// 计算器相关
const inputStack = ref([]);
const operator = ref('');
const isNewInput = ref(true);
const calculationDisplay = ref(''); // 用于显示计算表达式
const calculationState = ref('input'); // 用于跟踪计算状态: 'input', 'operator', 'second'

// 编辑模式
const isEdit = ref(false);
const transactionId = ref(null);

// 分页总数
const totalPages = ref(1);

// 图片列表
const imageList = ref([]);

// 组件引用
const platformPopup = ref(null);
const imageManagerPopup = ref(null);

// 图片管理相关
const isUploading = ref(false);

// 添加后台上传相关变量
const backgroundUploadInProgress = ref(false);

// 计算属性
const displayAmount = computed(() => {
  if (calculationDisplay.value) {
    return calculationDisplay.value;
  }
  
  if (formData.amount === '') {
    return '0.00';
  }
  
  return formData.amount;
});

// 页面加载生命周期
onLoad((e) => {
  // 判断是否为编辑模式
  if (e.id) {
    isEdit.value = true;
    transactionId.value = e.id;
    // 加载交易详情
    loadTransactionDetail(e.id);
  } else {
    // 如果不是编辑模式，则使用上次选择的日期（如果存在）
    formData.transactionDate = lastSelectedDate.value;
  }
});

// 生命周期钩子
onMounted(() => {
  // 加载分类和平台数据
  resetAndFetchCategories();
  loadPlatforms();
  
  // 初始化日期时间选择器
  initDatePicker();
  
  // 初始化时，如果lastSelectedDate已有值，使用它
  if (lastSelectedDate.value && !isEdit.value) {
    formData.transactionDate = new Date(lastSelectedDate.value);
  }
});

// 初始化日期选择器
const initDatePicker = () => {
  // 初始化年份，从2010年到当前年份后5年
  const currentYear = new Date().getFullYear();
  years.value = [];
  for (let i = 2010; i <= currentYear + 5; i++) {
    years.value.push(i + '年');
  }
  
  // 初始化月份
  months.value = [];
  for (let i = 1; i <= 12; i++) {
    months.value.push(i.toString().padStart(2, '0') + '月');
  }
  
  // 初始化天数
  updateDays(new Date().getFullYear(), new Date().getMonth() + 1);
  
  // 初始化小时
  hours.value = [];
  for (let i = 0; i < 24; i++) {
    hours.value.push(i.toString().padStart(2, '0') + '时');
  }
  
  // 初始化分钟
  minutes.value = [];
  for (let i = 0; i < 60; i++) {
    minutes.value.push(i.toString().padStart(2, '0') + '分');
  }
  
  // 设置当前日期时间的索引
  setDatePickerValue(formData.transactionDate);
};

// 更新天数
const updateDays = (year, month) => {
  const daysInMonth = new Date(year, month, 0).getDate();
  days.value = [];
  for (let i = 1; i <= daysInMonth; i++) {
    days.value.push(i.toString().padStart(2, '0') + '日');
  }
};

// 设置日期选择器的值
const setDatePickerValue = (date) => {
  const d = new Date(date);
  const yearIndex = d.getFullYear() - 2010;
  const monthIndex = d.getMonth();
  const dayIndex = d.getDate() - 1;
  const hourIndex = d.getHours();
  const minuteIndex = d.getMinutes();
  
  datePickerValue.value = [
    yearIndex >= 0 ? yearIndex : 0,
    monthIndex,
    dayIndex,
    hourIndex,
    minuteIndex
  ];
};

// 日期选择器变化事件
const onDatePickerChange = (e) => {
  e.preventDefault && e.preventDefault();
  e.stopPropagation && e.stopPropagation();
  
  const values = e.detail.value;
  datePickerValue.value = values;
  
  // 如果年或月变化，需要更新天数
  const year = 2010 + values[0];
  const month = values[1] + 1;
  
  // 检查天数是否需要更新
  const currentDays = days.value.length;
  const daysInMonth = new Date(year, month, 0).getDate();
  
  if (currentDays !== daysInMonth) {
    updateDays(year, month);
    
    // 如果选中的日期超出了当月的天数，则调整为当月最后一天
    if (values[2] >= daysInMonth) {
      datePickerValue.value[2] = daysInMonth - 1;
    }
  }
};

// 重置分类数据并重新加载
const resetAndFetchCategories = () => {
  categoryList.value = [];
  page.value = 1;
  totalPages.value = 1; // 重置总页数
  loading.value = true;
  loadMoreStatus.value = 'more';
  fetchCategoryList();
};

// 获取分类列表
const fetchCategoryList = async () => {
  if (page.value > totalPages.value && totalPages.value > 0) {
    loadMoreStatus.value = 'noMore';
    return;
  }
  
  loadMoreStatus.value = 'loading';
  
  try {
    const params = {
      spend: activeTab.value === 'expense' ? 1 : 0,
      page: page.value,
      pageSize: pageSize
    };
    
    const res = await queryCategories(params);
    if (res.data && (res.data.code === 1 || res.data.code === 200)) {
      const { records, pages } = res.data.data;
      
      // 使用展开运算符累加数据
      if (page.value === 1) {
        // 第一页数据直接替换
        categoryList.value = records || [];
      } else {
        // 后续页面追加数据
        categoryList.value = [...categoryList.value, ...records];
      }
      
      // 更新总页数
      totalPages.value = pages;
      
      // 更新加载状态
      loadMoreStatus.value = page.value >= totalPages.value ? 'noMore' : 'more';
      
      // 更新页码
      page.value++;
    } else {
      loadMoreStatus.value = 'noMore';
      uni.showToast({
        title: '获取分类失败',
        icon: 'none'
      });
    }
  } catch (error) {
    console.error('获取分类列表失败:', error);
    loadMoreStatus.value = 'noMore';
    uni.showToast({
      title: '获取分类失败',
      icon: 'none'
    });
  } finally {
    loading.value = false;
  }
};

// 加载更多分类
const loadMoreCategories = () => {
  if (loadMoreStatus.value !== 'more') return;
  fetchCategoryList();
};

// 加载平台数据
const loadPlatforms = async () => {
  try {
    // 添加随机参数防止缓存导致的CORS问题
    const timestamp = new Date().getTime();
    const res = await queryPlatforms({ _t: timestamp });
    if (res.data && (res.data.code === 1 || res.data.code === 200)) {
      platforms.value = res.data.data.records || [];
      
      // 默认选中第一个平台
      if (platforms.value.length > 0) {
        selectedPlatform.value = platforms.value[0];
        formData.platformId = platforms.value[0].id;
      }
    }
  } catch (error) {
    console.error('加载平台失败:', error);
    // 失败后延迟重试一次
    setTimeout(() => {
      console.log('正在重试加载平台...');
      try {
        queryPlatforms({ _t: new Date().getTime() }).then(retryRes => {
          if (retryRes.data && (retryRes.data.code === 1 || retryRes.data.code === 200)) {
            platforms.value = retryRes.data.data.records || [];
            if (platforms.value.length > 0) {
              selectedPlatform.value = platforms.value[0];
              formData.platformId = platforms.value[0].id;
            }
          }
        }).catch(retryErr => {
          console.error('重试加载平台失败:', retryErr);
    uni.showToast({
      title: '加载平台失败',
      icon: 'none'
    });
        });
      } catch (retryError) {
        console.error('重试加载平台出错:', retryError);
      }
    }, 1000);
  }
};

// 切换标签页
const switchTab = (tab) => {
  // 如果已经是当前标签，不做任何操作
  if (activeTab.value === tab) return;
  
  activeTab.value = tab;
  swiperCurrent.value = tab === 'expense' ? 0 : 1;
  formData.type = tab === 'expense' ? 0 : 1;
  selectedCategory.value = {};
  formData.categoryId = null;
  
  // 完全清空数据并重新加载
  categoryList.value = [];
  page.value = 1;
  totalPages.value = 1;
  loading.value = true;
  loadMoreStatus.value = 'more';
  
  // 直接加载数据，不使用nextTick
  fetchCategoryList();
};

// 滑动切换回调
const onSwiperChange = (e) => {
  const current = e.detail.current;
  // 如果当前页面索引没有变化，不做任何操作
  if (swiperCurrent.value === current) return;
  
  swiperCurrent.value = current;
  activeTab.value = current === 0 ? 'expense' : 'income';
  formData.type = current === 0 ? 0 : 1;
  selectedCategory.value = {};
  formData.categoryId = null;
  
  // 完全清空数据并重新加载
  categoryList.value = [];
  page.value = 1;
  totalPages.value = 1;
  loading.value = true;
  loadMoreStatus.value = 'more';
  
  // 直接加载数据，不使用nextTick
  fetchCategoryList();
};

// 选择分类
const selectCategory = (category) => {
  selectedCategory.value = category;
  formData.categoryId = category.id;
};

// 显示平台选择器
const showPlatformSelector = () => {
  platformPopup.value.open();
};

// 关闭平台选择器
const closePlatformPopup = () => {
  platformPopup.value.close();
};

// 选择平台
const selectPlatform = (platform) => {
  selectedPlatform.value = platform;
  formData.platformId = platform.id;
  closePlatformPopup();
};

// 显示日期选择器
const showDatePicker = (e) => {
  if (e) {
    e.preventDefault && e.preventDefault();
    e.stopPropagation && e.stopPropagation();
  }
  
  // 更新日期选择器的值，使用上次选择的日期或当前表单日期
  setDatePickerValue(formData.transactionDate);
  
  // 确保键盘收起
  uni.hideKeyboard && uni.hideKeyboard();
  
  // 延迟打开弹窗，确保键盘已经完全收起
  setTimeout(() => {
    datePopup.value.open();
  }, 100);
};

// 日期选择确认
const onDateTimeConfirm = (e) => {
  e && e.preventDefault && e.preventDefault();
  e && e.stopPropagation && e.stopPropagation();
  
  const [yearIndex, monthIndex, dayIndex, hourIndex, minuteIndex] = datePickerValue.value;
  
  const year = 2010 + yearIndex;
  const month = monthIndex + 1;
  const day = dayIndex + 1;
  const hour = hourIndex;
  const minute = minuteIndex;
  
  formData.transactionDate = new Date(year, month - 1, day, hour, minute, 0);
  // 保存选择的时间，用于下次打开时使用
  lastSelectedDate.value = new Date(formData.transactionDate);
  datePopup.value.close();
};

// 日期选择取消
const onDateTimeCancel = (e) => {
  e && e.preventDefault && e.preventDefault();
  e && e.stopPropagation && e.stopPropagation();
  
  datePopup.value.close();
};

// 格式化日期显示
const formatDate = (date) => {
  if (!date) return '今天';
  
  const today = new Date();
  const inputDate = new Date(date);
  
  // 判断是否为今天
  if (
    today.getFullYear() === inputDate.getFullYear() &&
    today.getMonth() === inputDate.getMonth() &&
    today.getDate() === inputDate.getDate()
  ) {
    return '今天 ' + formatTime(inputDate);
  }
  
  // 格式化为 MM.DD HH:mm
  const month = (inputDate.getMonth() + 1).toString().padStart(2, '0');
  const day = inputDate.getDate().toString().padStart(2, '0');
  return `${month}.${day} ${formatTime(inputDate)}`;
};

// 格式化时间
const formatTime = (date) => {
  const hours = date.getHours().toString().padStart(2, '0');
  const minutes = date.getMinutes().toString().padStart(2, '0');
  return `${hours}:${minutes}`;
};

// 处理键盘输入
const inputKey = (key) => {
  // 处理数字和小数点
  if (key === '.' || /^\d$/.test(key)) {
    if (isNewInput.value) {
      // 新输入，清空当前值
      formData.amount = key === '.' ? '0.' : key;
      isNewInput.value = false;
      
      // 如果处于运算符状态，切换到第二个操作数状态
      if (calculationState.value === 'operator') {
        calculationState.value = 'second';
      } else {
        calculationState.value = 'input';
      }
    } else {
      // 继续输入
      // 小数点只能输入一次
      if (key === '.' && formData.amount.includes('.')) {
        return;
      }
      
      // 限制小数点后两位
      if (formData.amount.includes('.')) {
        const parts = formData.amount.split('.');
        if (parts[1] && parts[1].length >= 2 && key !== '.') {
          return;
        }
      }
      
      formData.amount += key;
    }
    
    // 更新显示
    updateCalculationDisplay();
  }
  // 处理运算符
  else if (key === '+' || key === '-') {
    // 如果已经有运算符且已经输入了第二个数，先计算结果
    if (operator.value && !isNewInput.value && calculationState.value === 'second') {
      calculate();
    }
    
    // 设置新的运算符
    operator.value = key;
    inputStack.value[0] = parseFloat(formData.amount) || 0;
    isNewInput.value = true;
    calculationState.value = 'operator';
    
    // 立即更新显示的计算表达式
    updateCalculationDisplay();
  }
};

// 更新计算表达式显示
const updateCalculationDisplay = () => {
  if (operator.value) {
    if (calculationState.value === 'operator') {
      // 只显示第一个数字和运算符
      calculationDisplay.value = `${inputStack.value[0]} ${operator.value}`;
    } else {
      // 显示完整表达式
      calculationDisplay.value = `${inputStack.value[0]} ${operator.value} ${formData.amount || ''}`;
    }
  } else {
    calculationDisplay.value = '';
  }
};

// 删除键 - 优化版本
const deleteKey = () => {
  // 如果在第二个操作数状态，删除第二个操作数的字符
  if (calculationState.value === 'second' && formData.amount.length > 0) {
    formData.amount = formData.amount.slice(0, -1);
    if (formData.amount === '') {
      // 如果第二个操作数被完全删除，回到运算符状态
      calculationState.value = 'operator';
    }
    updateCalculationDisplay();
    return;
  }
  
  // 如果在运算符状态，删除运算符并回到第一个操作数状态
  if (calculationState.value === 'operator') {
    operator.value = '';
    calculationState.value = 'input';
    isNewInput.value = false;
    calculationDisplay.value = '';
    return;
  }
  
  // 在输入第一个操作数状态
  if (calculationState.value === 'input' && formData.amount.length > 0) {
    formData.amount = formData.amount.slice(0, -1);
  }
};

// 计算结果
const calculate = () => {
  if (!operator.value || isNewInput.value) return;
  
  const num1 = inputStack.value[0] || 0;
  const num2 = parseFloat(formData.amount) || 0;
  
  let result = 0;
  switch (operator.value) {
    case '+':
      result = num1 + num2;
      break;
    case '-':
      result = num1 - num2;
      break;
  }
  
  // 保留两位小数
  formData.amount = result.toFixed(2).replace(/\.00$/, '');
  operator.value = '';
  inputStack.value = [];
  calculationDisplay.value = '';
  calculationState.value = 'input';
  isNewInput.value = false;
};

// 处理图片操作（选择或管理）
const handleImageAction = () => {
  if (imageList.value.length === 0) {
    // 没有图片，直接选择
    chooseImage();
  } else {
    // 已有图片，打开管理页面
    imageManagerPopup.value.open();
  }
};

// 选择图片
const chooseImage = () => {
  // 使用回调方式而非async/await，避免可能的Promise问题
  uni.chooseImage({
    count: 9 - imageList.value.length, // 最多9张图片
    sizeType: ['original'], // 使用原图，后续自己压缩
    sourceType: ['album', 'camera'],
    success: (res) => {
      if (res && res.tempFilePaths && res.tempFilePaths.length > 0) {
        // 处理选择的图片
        for (let i = 0; i < res.tempFilePaths.length; i++) {
          const tempPath = res.tempFilePaths[i];
          const originalSize = res.tempFiles[i].size;
          
          // 打印原始大小
          console.log(`图片原始大小: ${(originalSize / 1024).toFixed(2)}KB`);
          
          // 添加到图片列表，先使用原图
          const imageItem = {
            path: tempPath,
            uploaded: false, // 标记为未上传
            uploading: false, // 标记为未在上传中
            compressing: true, // 标记为正在压缩中
            originalSize: originalSize, // 原始大小(字节)
            compressedSize: 0, // 压缩后大小(字节)
            compressionRatio: 0 // 压缩比例
          };
          
          imageList.value.push(imageItem);
          
          // 获取当前添加的图片索引
          const currentIndex = imageList.value.length - 1;
          
          // 尝试压缩图片（不阻塞UI）
          compressImage(tempPath).then(result => {
            // 更新图片状态
            if (imageList.value[currentIndex]) {
              // 如果返回的是对象(包含路径和大小)
              if (typeof result === 'object' && result.path) {
                imageList.value[currentIndex].path = result.path;
                imageList.value[currentIndex].compressedSize = result.size || 0;
              } else {
                // 如果只返回了路径
                imageList.value[currentIndex].path = result;
                // 尝试获取压缩后的大小
                getFileSize(result).then(size => {
                  imageList.value[currentIndex].compressedSize = size;
                  calculateCompressionRatio(currentIndex);
                });
              }
              
              imageList.value[currentIndex].compressing = false;
              
              // 如果已知压缩后大小，计算压缩比例
              if (imageList.value[currentIndex].compressedSize > 0) {
                calculateCompressionRatio(currentIndex);
              }
              
              // 显示压缩结果
              showCompressionResult(currentIndex);
            }
          }).catch(error => {
            console.error('压缩图片失败:', error);
            // 压缩失败也要更新状态
            if (imageList.value[currentIndex]) {
              imageList.value[currentIndex].compressing = false;
              imageList.value[currentIndex].compressionError = true;
            }
          });
        }
      }
    },
    fail: (err) => {
      // 只有在非取消的情况下才显示错误提示
      if (err.errMsg && !err.errMsg.includes('cancel')) {
        console.error('选择图片失败:', err);
        uni.showToast({
          title: '选择图片失败',
          icon: 'none'
        });
      }
    }
  });
};

// 获取文件大小
const getFileSize = (filePath) => {
  return new Promise((resolve) => {
    // 尝试使用uni.getFileInfo获取文件大小
    if (typeof uni.getFileInfo === 'function') {
      uni.getFileInfo({
        filePath: filePath,
        success: (res) => {
          resolve(res.size);
        },
        fail: () => {
          // 如果失败，返回0
          resolve(0);
        }
      });
    } else {
      // 如果不支持getFileInfo，返回0
      resolve(0);
    }
  });
};

// 计算压缩比例
const calculateCompressionRatio = (index) => {
  const item = imageList.value[index];
  if (item && item.originalSize && item.compressedSize) {
    item.compressionRatio = ((1 - item.compressedSize / item.originalSize) * 100).toFixed(2);
  }
};

// 显示压缩结果
const showCompressionResult = (index) => {
  const item = imageList.value[index];
  if (!item) return;
  
  const originalSizeKB = (item.originalSize / 1024).toFixed(2);
  const compressedSizeKB = (item.compressedSize / 1024).toFixed(2);
  
  console.log(`图片压缩结果 - 原始: ${originalSizeKB}KB, 压缩后: ${compressedSizeKB}KB, 压缩率: ${item.compressionRatio}%`);
  
  // 如果压缩率超过5%，显示提示
  if (item.compressionRatio > 5) {
    uni.showToast({
      title: `压缩成功: 减少${item.compressionRatio}%`,
      icon: 'none',
      duration: 1500
    });
  }
};

// 压缩图片
const compressImage = (tempPath) => {
  return new Promise((resolve, reject) => {
    console.log('使用uni.compressImage压缩图片...');
    
    // 使用uni-app自带的压缩功能
    uni.compressImage({
      src: tempPath,
      quality: 80, // 压缩质量0-100
      width: 1280, // 压缩后的最大宽度
      success: (res) => {
        console.log('uni.compressImage成功');
        // 获取压缩后文件大小
        getFileSize(res.tempFilePath).then(size => {
          resolve({
            path: res.tempFilePath,
            size: size
          });
        });
      },
      fail: (err) => {
        console.warn('压缩图片失败，使用原图:', err);
        // 压缩失败时使用原图
        getFileSize(tempPath).then(size => {
          resolve({
            path: tempPath,
            size: size
          });
        });
      }
    });
  });
};

// 预览图片
const previewImage = (index) => {
  const urls = imageList.value.map(item => item.path);
  uni.previewImage({
    urls: urls,
    current: index
  });
};

// 显示删除确认
const showDeleteConfirm = (index) => {
  uni.showModal({
    title: '删除提示',
    content: '确定要删除这张图片吗？',
    success: (res) => {
      if (res.confirm) {
        imageList.value.splice(index, 1);
      }
    }
  });
};

// 关闭图片管理器
const closeImageManager = () => {
  imageManagerPopup.value.close();
};

// 获取API基础URL
const getBaseUrl = () => {
  try {
    // 尝试从env.js中获取
    const env = require('@/env.js');
    if (env && env.BASE_URL) {
      console.log('从env.js获取BASE_URL:', env.BASE_URL);
      return env.BASE_URL;
    }
  } catch (e) {
    console.warn('无法从env.js获取BASE_URL:', e);
  }
  
  try {
    // 尝试从环境变量获取
    if (import.meta && import.meta.env && import.meta.env.VITE_APP_BASE_API) {
      console.log('从环境变量获取BASE_URL:', import.meta.env.VITE_APP_BASE_API);
      return import.meta.env.VITE_APP_BASE_API;
    }
  } catch (e) {
    console.warn('无法从环境变量获取基础URL:', e);
  }
  
  // 如果都获取失败，使用默认值
  console.warn('使用默认BASE_URL: http://bookkeeping.rwklyd.cn:9191');
  return 'http://bookkeeping.rwklyd.cn:9191';
};

// 上传所有图片
const uploadAllImages = async (transactionId) => {
  if (imageList.value.length === 0) return [];
  
  const uploadedUrls = [];
  const token = uni.getStorageSync('Authorization');
  
  if (!token) {
    throw new Error('未登录或token已过期');
  }
  
  // 标记所有图片为上传中
  imageList.value.forEach(item => {
    item.uploading = true;
  });
  
  isUploading.value = true;
  
  try {
    // 并行上传所有图片
    const uploadPromises = imageList.value.map(async (item, index) => {
      if (item.uploaded) {
        // 已上传过的图片，直接返回URL
        return item.url;
      }
      
      // 如果图片还在压缩中，等待压缩完成
      if (item.compressing) {
        await new Promise(resolve => {
          // 每100ms检查一次压缩状态
          const checkCompression = () => {
            if (!item.compressing) {
              resolve();
            } else {
              setTimeout(checkCompression, 100);
            }
          };
          checkCompression();
        });
      }
      
      try {
        const uploadResult = await new Promise((resolve, reject) => {
          // 处理base64格式的图片
          let filePath = item.path;
          let isBase64 = false;
          
          // 检查是否是base64格式
          if (typeof filePath === 'string' && filePath.indexOf('data:image') === 0) {
            isBase64 = true;
            // 在小程序环境下，需要先将base64转为临时文件
            // #ifdef MP
            const fs = uni.getFileSystemManager();
            const tempFilePath = `${wx.env.USER_DATA_PATH}/${Date.now()}.jpg`;
            const base64Data = filePath.replace(/^data:image\/\w+;base64,/, '');
            
            try {
              fs.writeFileSync(
                tempFilePath,
                base64Data,
                'base64'
              );
              filePath = tempFilePath;
              isBase64 = false;
            } catch (fsError) {
              console.error('转换base64到文件失败:', fsError);
              reject(new Error('转换base64到文件失败'));
              return;
            }
            // #endif
          }
          
          uni.showLoading({
            title: '上传中...',
            mask: true
          });
          
          // 使用uni.uploadFile上传图片，参考upload-file组件的实现
          const baseUrl = getBaseUrl();
          const uploadTask = uni.uploadFile({
            // 使用getBaseUrl()获取基础URL
            url: `${baseUrl}/admin/common/upload`,
            filePath: filePath,
            name: 'file',
            formData: {
              folderPath: 'APP/PiggyBank/transaction'
            },
            header: {
              'Authorization': token
            },
            success: (uploadFileRes) => {
              uni.hideLoading();
              try {
                const res = JSON.parse(uploadFileRes.data);
                if (res.code === 1 || res.code === 200) {
                  resolve(res.data);
                } else {
                  reject(new Error(res.msg || '上传失败'));
                }
              } catch (e) {
                reject(new Error('解析响应数据失败'));
              }
            },
            fail: (err) => {
              uni.hideLoading();
              console.error('Upload failed:', err);
              reject(new Error(err.errMsg || '上传失败'));
            }
          });
          
          // 监听上传进度
          if (uploadTask && uploadTask.onProgressUpdate) {
            uploadTask.onProgressUpdate((res) => {
              // 更新当前图片的上传进度
              item.progress = res.progress;
            });
          }
        });
        
        // 上传成功，更新图片状态
        item.uploaded = true;
        item.uploading = false;
        item.url = uploadResult;
        
        return uploadResult;
      } catch (error) {
        console.error(`上传第${index + 1}张图片失败:`, error);
        // 上传失败，标记状态
        item.uploading = false;
        item.error = true;
        throw error;
      }
    });
    
    // 等待所有上传完成
    const results = await Promise.all(uploadPromises);
    return results.filter(url => url); // 过滤掉可能的空值
  } catch (error) {
    console.error('上传图片过程中出错:', error);
    throw error;
  } finally {
    isUploading.value = false;
  }
};

// 提交交易记录
const submitTransaction = async () => {
  // 先计算最终结果
  if (operator.value) {
    calculate();
  }
  
  // 验证表单
  if (!formData.categoryId) {
    uni.showToast({
      title: '请选择分类',
      icon: 'none'
    });
    return;
  }
  
  if (!formData.amount || parseFloat(formData.amount) <= 0) {
    uni.showToast({
      title: '请输入有效金额',
      icon: 'none'
    });
    return;
  }
  
  try {
    uni.showLoading({
      title: isEdit.value ? '更新中...' : '添加中...',
      mask: true
    });
    
    // 格式化日期为 yyyy-MM-dd HH:mm:ss
    const formatDateTime = (date) => {
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, '0');
      const day = date.getDate().toString().padStart(2, '0');
      const hours = date.getHours().toString().padStart(2, '0');
      const minutes = date.getMinutes().toString().padStart(2, '0');
      const seconds = date.getSeconds().toString().padStart(2, '0');
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    };
    
    const transactionData = {
      ...formData,
      amount: parseFloat(formData.amount),
      transactionDate: formatDateTime(formData.transactionDate)
    };
    
    let transId;
    
    // 编辑模式需要添加ID
    if (isEdit.value) {
      transactionData.id = transactionId.value;
      await updateTransaction(transactionData);
      transId = transactionId.value;
    } else {
      const res = await addTransaction(transactionData);
      // 获取新增的交易ID
      if (res.data && (res.data.code === 1 || res.data.code === 200)) {
        transId = res.data.data;
      }
    }
    
    // 隐藏加载提示
    uni.hideLoading();
    
    // 立即显示成功提示，不等待图片上传
    uni.showToast({
      title: isEdit.value ? '更新成功' : '添加成功',
      icon: 'success'
    });
    
    // 提交成功后，重置表单，但保留选择的日期
    if (!isEdit.value) {
      // 重置表单数据，但保留日期和类型
      const currentType = formData.type;
      const currentCategory = selectedCategory.value;
      const currentPlatform = selectedPlatform.value;
      
      formData.amount = '';
      formData.remark = '';
      // 保留之前选择的日期
      // formData.transactionDate 保持不变
      
      // 保留选择的分类和平台
      formData.categoryId = currentCategory.id;
      formData.platformId = currentPlatform.id;
      formData.type = currentType;
      
      // 重置计算器状态
      isNewInput.value = true;
      calculationState.value = 'input';
      operator.value = '';
      calculationDisplay.value = '';
      inputStack.value = [];
    }
    
    // 判断是否需要上传图片
    const needUploadImages = () => {
      // 新增模式下有图片需要上传
      if (!isEdit.value && imageList.value.length > 0) {
        return true;
      }
      
      // 编辑模式下，检查是否有新增的图片（未上传过的图片）
      if (isEdit.value) {
        return imageList.value.some(item => !item.uploaded);
      }
      
      return false;
    };
    
    // 如果有新图片需要上传，在后台处理上传
    if (needUploadImages() && transId) {
      // 复制需要上传的图片列表和交易ID，用于后台上传
      // 在编辑模式下，只上传未上传过的图片
      const imagesToUpload = isEdit.value 
        ? JSON.parse(JSON.stringify(imageList.value.filter(item => !item.uploaded)))
        : JSON.parse(JSON.stringify(imageList.value));
        
      const transactionIdForUpload = transId;
      
      // 如果确实有图片需要上传
      if (imagesToUpload.length > 0) {
        // 提示用户图片将在后台上传
        uni.showToast({
          title: '图片将在后台上传',
          icon: 'none',
          duration: 1500
        });
        
        // 如果不是编辑模式，清空当前页面的图片列表
        if (!isEdit.value) {
          imageList.value = [];
        }
        
        // 在后台上传图片（不等待完成）
        backgroundUploadInProgress.value = true;
        setTimeout(() => {
          backgroundUploadImages(transactionIdForUpload, imagesToUpload);
        }, 500);
      }
    }
    
    // 只有编辑模式才返回上一页
    if (isEdit.value) {
      setTimeout(() => {
        uni.navigateBack();
      }, 1500);
    }
  } catch (error) {
      uni.hideLoading();
    console.error(isEdit.value ? '更新交易失败:' : '添加交易失败:', error);
    uni.showToast({
      title: isEdit.value ? '更新失败' : '添加失败',
      icon: 'none'
    });
  }
};

// 后台上传图片
const backgroundUploadImages = async (transId, images) => {
  console.log('开始后台上传图片, 交易ID:', transId);
  
  if (!images || images.length === 0 || !transId) {
    console.error('上传参数无效，取消上传');
    backgroundUploadInProgress.value = false;
    return;
  }
  
  const token = uni.getStorageSync('Authorization');
  if (!token) {
    console.error('未登录或token已过期，无法上传图片');
    backgroundUploadInProgress.value = false;
    return;
  }
      
      try {
        // 上传所有图片
    const uploadPromises = images.map(async (item, index) => {
      // 如果图片已经上传过，直接返回URL
      if (item.uploaded && item.url) {
        return item.url;
      }
      
      // 如果图片还在压缩中，等待压缩完成
      if (item.compressing) {
        await new Promise(resolve => {
          const checkCompression = () => {
            if (!item.compressing) {
              resolve();
            } else {
              setTimeout(checkCompression, 100);
            }
          };
          checkCompression();
        });
      }
      
      try {
        return await uploadImageWithRetry(item, token, index);
      } catch (error) {
        console.error(`上传第${index + 1}张图片失败:`, error);
        return null;
      }
    });
    
    // 等待所有上传完成
    const results = await Promise.all(uploadPromises);
    const uploadedUrls = results.filter(url => url); // 过滤掉失败的上传
    
    console.log('图片上传完成，共上传成功:', uploadedUrls.length, '张，交易ID:', transId);
    
    // 如果有成功上传的图片，更新交易记录
        if (uploadedUrls.length > 0) {
      // 如果是编辑模式，需要合并已有的图片URL和新上传的URL
      if (isEdit.value) {
        // 获取当前交易详情，确保获取最新的凭证图片
        try {
          const res = await queryTransactions({ id: transId });
          if (res.data && (res.data.code === 200 || res.data.code === 1)) {
            const records = res.data.code === 200 ? res.data.data.records : res.data.records;
            
            if (records && records.length > 0) {
              const detail = records[0];
              
              // 获取现有的凭证图片
              let existingUrls = [];
              if (detail.receiptImage) {
                existingUrls = detail.receiptImage.split(',');
              }
              
              // 合并现有URL和新上传的URL，去重
              const allUrls = [...new Set([...existingUrls, ...uploadedUrls])];
              
              // 更新凭证
          await updateTransactionReceipt({
                id: transId,
                receiptImage: allUrls.join(',')
          });
          }
        }
      } catch (error) {
          console.error('获取交易详情失败:', error);
          
          // 如果获取失败，直接更新新上传的图片
          await updateTransactionReceipt({
            id: transId,
            receiptImage: uploadedUrls.join(',')
          });
        }
      } else {
        // 新增模式直接更新
        await updateTransactionReceipt({
          id: transId,
          receiptImage: uploadedUrls.join(',')
        });
      }
      
      console.log('后台图片上传和更新凭证成功');
    }
  } catch (error) {
    console.error('后台上传图片过程中出错:', error);
  } finally {
    backgroundUploadInProgress.value = false;
  }
};

// 带重试机制的上传单张图片
const uploadImageWithRetry = async (item, token, index) => {
  const MAX_RETRY = 3;
  let retryCount = 0;
  let lastError = null;
  
  while (retryCount < MAX_RETRY) {
    try {
      return await uploadSingleImage(item, token);
  } catch (error) {
      lastError = error;
      retryCount++;
      
      if (retryCount < MAX_RETRY) {
        console.log(`上传第${index + 1}张图片失败，将进行第${retryCount}次重试`);
        // 等待一段时间再重试
        await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
      } else {
        console.error(`上传第${index + 1}张图片失败，已达到最大重试次数:`, error);
        throw error;
      }
    }
  }
  
  throw lastError;
};

// 上传单张图片
const uploadSingleImage = (item, token) => {
  return new Promise((resolve, reject) => {
    // 处理base64格式的图片
    let filePath = item.path;
    let isBase64 = false;
    
    // 检查是否是base64格式
    if (typeof filePath === 'string' && filePath.indexOf('data:image') === 0) {
      isBase64 = true;
      // 在小程序环境下，需要先将base64转为临时文件
      // #ifdef MP
      const fs = uni.getFileSystemManager();
      const tempFilePath = `${wx.env.USER_DATA_PATH}/${Date.now()}.jpg`;
      const base64Data = filePath.replace(/^data:image\/\w+;base64,/, '');
      
      try {
        fs.writeFileSync(
          tempFilePath,
          base64Data,
          'base64'
        );
        filePath = tempFilePath;
        isBase64 = false;
      } catch (fsError) {
        console.error('转换base64到文件失败:', fsError);
        reject(new Error('转换base64到文件失败'));
        return;
      }
      // #endif
    }
    
    // 使用uni.uploadFile上传图片
    try {
      const baseUrl = getBaseUrl();
      console.log('上传图片使用的baseUrl:', baseUrl);
      
      if (!baseUrl) {
        reject(new Error('无法获取API基础URL'));
        return;
      }
      
      const uploadTask = uni.uploadFile({
        url: `${baseUrl}/admin/common/upload`,
        filePath: filePath,
        name: 'file',
        formData: {
          folderPath: 'APP/PiggyBank/transaction'
        },
        header: {
          'Authorization': token
        },
        success: (uploadFileRes) => {
          try {
            const res = JSON.parse(uploadFileRes.data);
            if (res.code === 1 || res.code === 200) {
              resolve(res.data);
            } else {
              reject(new Error(res.msg || '上传失败'));
            }
          } catch (e) {
            reject(new Error('解析响应数据失败'));
          }
        },
        fail: (err) => {
          console.error('Upload failed:', err);
          reject(new Error(err.errMsg || '上传失败'));
        }
      });
      
      // 监听上传进度
      if (uploadTask && uploadTask.onProgressUpdate) {
        uploadTask.onProgressUpdate((res) => {
          console.log(`后台上传进度: ${res.progress}%`);
        });
      }
    } catch (error) {
      reject(error);
    }
  });
};

// 加载交易详情（编辑模式）
const loadTransactionDetail = async (id) => {
  try {
    uni.showLoading({
      title: '加载中...',
      mask: true
    });
    
    const res = await queryTransactions({ id });
    if (res.data && (res.data.code === 200 || res.data.code === 1)) {
      // 兼容新旧API返回格式
      const records = res.data.code === 200 ? res.data.data.records : res.data.records;
      
      if (records && records.length > 0) {
        const detail = records[0]; // 获取第一条记录
        
        // 设置表单数据
        formData.categoryId = detail.categoryId;
        formData.platformId = detail.platformId;
        formData.amount = detail.amount.toString();
        formData.transactionDate = new Date(detail.transactionDate);
        formData.remark = detail.remark || '';
    
        // 处理凭证图片
        if (detail.receiptImage) {
          const imageUrls = detail.receiptImage.split(',');
          imageList.value = imageUrls.map(url => ({
            path: url,
            url: url,
            uploaded: true,
            uploading: false
          }));
        }
        
        // 根据分类的spend字段判断是支出还是收入
        // 支出为1，收入为0
        const isExpense = detail.category && detail.category.spend === 1;
        formData.type = isExpense ? 0 : 1; // 表单中支出为0，收入为1
        
        // 设置当前标签页
        activeTab.value = isExpense ? 'expense' : 'income';
        swiperCurrent.value = isExpense ? 0 : 1;
        
        // 设置选中的分类
        if (detail.category) {
          selectedCategory.value = detail.category;
        }
        
        // 设置选中的平台
        if (detail.platform) {
          selectedPlatform.value = detail.platform;
        }
        
        // 重置计算器状态
        isNewInput.value = false;
        calculationState.value = 'input';
        operator.value = '';
        calculationDisplay.value = '';
      }
    } else {
      uni.showToast({
        title: '获取交易详情失败',
        icon: 'none'
      });
    }
  } catch (error) {
    console.error('加载交易详情失败:', error);
    uni.showToast({
      title: '加载交易详情失败',
      icon: 'none'
    });
  } finally {
    uni.hideLoading();
  }
};

// 获取总压缩信息
const getTotalCompressionInfo = () => {
  let totalOriginalSize = 0;
  let totalCompressedSize = 0;
  let compressedCount = 0;
  
  imageList.value.forEach(item => {
    if (item.originalSize) {
      totalOriginalSize += item.originalSize;
      
      if (item.compressedSize && !item.compressing) {
        totalCompressedSize += item.compressedSize;
        compressedCount++;
      } else {
        // 如果还没压缩完，计入原始大小
        totalCompressedSize += item.originalSize;
      }
    }
  });
  
  // 如果没有压缩完成的图片，返回简单信息
  if (compressedCount === 0) {
    return `总大小: ${(totalOriginalSize / 1024 / 1024).toFixed(2)}MB`;
  }
  
  const savedSize = totalOriginalSize - totalCompressedSize;
  const savedPercent = ((savedSize / totalOriginalSize) * 100).toFixed(1);
  
  if (savedSize > 0) {
    return `已节省: ${(savedSize / 1024 / 1024).toFixed(2)}MB (${savedPercent}%)`;
  } else {
    return `总大小: ${(totalCompressedSize / 1024 / 1024).toFixed(2)}MB`;
  }
};
</script>

<style lang="scss">
.transaction-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f8f8f8;
}

/* 分段器样式 */
.segment-container {
  display: flex;
  padding: 20rpx 100rpx;
  background-color: #ffffff;
  border-bottom: 1rpx solid #f0f0f0;
  
  .segment-item {
    flex: 1;
    text-align: center;
    padding: 15rpx 0;
    font-size: 32rpx;
    color: #999;
    position: relative;
    
    &.active {
      color: #ff6b6b;
      font-weight: 500;
      
      &::after {
        content: '';
        position: absolute;
        bottom: -5rpx;
        left: 50%;
        transform: translateX(-50%);
        width: 60rpx;
        height: 6rpx;
        background-color: #ff6b6b;
        border-radius: 3rpx;
      }
    }
  }
}

/* 分类选择区域 */
.category-swiper {
  flex: 2;
  background-color: #ffffff;
  
  .category-scroll {
    height: 100%;
    padding: 20rpx 0;
  }
  
  .category-list {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: minmax(120rpx, auto);
    gap: 20rpx;
    padding: 20rpx;
  }
  
  .category-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 10rpx 0;
    
    &.active {
      .category-icon {
        border: 2rpx solid #ff6b6b;
        background-color: rgba(255, 107, 107, 0.1);
      }
      
      .category-name {
        color: #ff6b6b;
      }
    }
    
    .category-icon {
      width: 80rpx;
      height: 80rpx;
      border-radius: 50%;
      background-color: #f5f5f5;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-bottom: 10rpx;
      border: 2rpx solid transparent;
      
      image {
        width: 50rpx;
        height: 50rpx;
      }
    }
    
    .category-name {
      font-size: 24rpx;
      color: #666;
      text-align: center;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 100%;
    }
  }
  
  // 加载中
  .loading-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 100rpx 0;
    
    .loading-text {
      margin-top: 20rpx;
      font-size: 24rpx;
      color: #999;
    }
  }
}

/* 键盘顶部区域 */
.keyboard-header {
  display: flex;
  padding: 20rpx;
  background-color: #ffffff;
  border-top: 1rpx solid #f0f0f0;
  border-bottom: 1rpx solid #f0f0f0;
  
  .platform-selector {
    width: 80rpx;
    height: 80rpx;
    border-radius: 50%;
    background-color: #f5f5f5;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 20rpx;
    
    image {
      width: 40rpx;
      height: 40rpx;
    }
  }
  
  .input-area {
    flex: 1;
    display: flex;
    align-items: center;
    
    .remark-input {
      flex: 3;
      height: 100%;
      // border-bottom: 1rpx solid #f0f0f0;
      
      input {
        height: 100%;
        flex: 1;
        font-size: 28rpx;
      }
    }
    
    .amount-upload {
      flex: 2;
      height: 100%;
      display: flex;
      align-items: center;
      
      .amount-display {
        height: 100%;
        flex: 4;
        font-size: 32rpx;
        font-weight: 500;
        display: flex;
        align-items: center;
      }
      
      .upload-btn {
        flex: 1;
        display: flex;
        justify-content: flex-end;
        position: relative;
        
        image {
          width: 60rpx;
          height: 60rpx;
        }
        
        .image-badge {
          position: absolute;
          top: -10rpx;
          right: -10rpx;
          background-color: #ff6b6b;
          color: #ffffff;
          font-size: 20rpx;
          width: 36rpx;
          height: 36rpx;
          border-radius: 50%;
          display: flex;
          justify-content: center;
          align-items: center;
        }
      }
    }
  }
}

/* 自定义键盘 */
.custom-keyboard {
  flex: 1;
  display: flex;
  background-color: #f8f8f8;
  
  .number-keys {
    flex: 3;
    display: flex;
    flex-direction: column;
    
    .key-row {
      flex: 1;
      display: flex;
    }
  }
  
  .function-keys {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  
  .key {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #ffffff;
    margin: 1rpx;
    font-size: 36rpx;
    font-weight: 500;
    padding: 0;
    border: none;
    border-radius: 0;
    line-height: normal;
    
    &::after {
      border: none;
    }
    
    &.key-hover {
      background-color: #f0f0f0;
      opacity: 0.9;
    }
    
    &.date-key {
      font-size: 28rpx;
      color: #666;
    }
    
    &.operator-key {
      color: #ff6b6b;
    }
    
    &.submit-key {
      background-color: #ff6b6b;
      color: #ffffff;
      
      &.key-hover {
        background-color: #e05a5a;
      }
    }
  }
}

/* 平台选择弹窗 */
.popup-content {
  background-color: #ffffff;
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
  padding-bottom: 30rpx;
  
  .popup-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 30rpx;
    border-bottom: 1rpx solid #f0f0f0;
    
    text {
      font-size: 32rpx;
      font-weight: 500;
    }
    
    .close-btn {
      width: 60rpx;
      height: 60rpx;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
  
  .platform-scroll {
    max-height: 600rpx;
    padding: 20rpx 0;
  }
  
  .platform-list {
    display: flex;
    flex-wrap: wrap;
    padding: 0 20rpx;
  }
  
  .platform-item {
    width: 20%;
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 30rpx;
    
    &.active {
      .platform-icon {
        border: 2rpx solid #ff6b6b;
        background-color: rgba(255, 107, 107, 0.1);
      }
      
      .platform-name {
        color: #ff6b6b;
      }
    }
    
    .platform-icon {
      width: 80rpx;
      height: 80rpx;
      border-radius: 50%;
      background-color: #f5f5f5;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-bottom: 10rpx;
      border: 2rpx solid transparent;
      
      image {
        width: 50rpx;
        height: 50rpx;
      }
    }
    
    .platform-name {
      font-size: 24rpx;
      color: #666;
      text-align: center;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 100%;
    }
  }
}

/* 日期选择器弹窗 */
.date-picker-popup {
  .picker-container {
    height: 400rpx;
    width: 100%;
    padding: 20rpx 0;
    touch-action: none; /* 防止触摸事件穿透 */
  }
  
  .picker-view {
    width: 100%;
    height: 400rpx;
    touch-action: none; /* 防止触摸事件穿透 */
  }
  
  .picker-item {
    line-height: 40px;
    text-align: center;
    font-size: 28rpx;
    color: #333;
    pointer-events: none; /* 防止单独的项目触发事件 */
  }
  
  .popup-footer {
    padding: 20rpx 30rpx;
    border-top: 1rpx solid #f0f0f0;
    
    .confirm-btn {
      background-color: #ff6b6b;
      color: #ffffff;
      border-radius: 8rpx;
      font-size: 30rpx;
      height: 80rpx;
      line-height: 80rpx;
      
      &::after {
        border: none;
      }
    }
  }
}

/* 图片预览和管理页面 */
.image-manager-container {
  width: 650rpx;
  background-color: #ffffff;
  border-radius: 20rpx;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: 80vh;
  
  .popup-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 30rpx;
    border-bottom: 1rpx solid #f0f0f0;
    
    text {
      font-size: 32rpx;
      font-weight: 500;
    }
    
    .close-btn {
      width: 60rpx;
      height: 60rpx;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
  
  .image-list-scroll {
    padding: 20rpx;
    max-height: 60vh;
  }
  
  .image-list {
    display: flex;
    flex-wrap: wrap;
    
    .image-item {
      width: 180rpx;
      height: 180rpx;
      margin: 10rpx;
      border-radius: 10rpx;
      overflow: hidden;
      position: relative;
      
      image {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
      
      &.add-image {
        border: 2rpx dashed #DDDDDD;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #f8f8f8;
      }
      
      .image-status {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        
        .status-text {
          color: #ffffff;
          font-size: 24rpx;
        }
      }
      
      .image-info {
        position: absolute;
        bottom: 0;
        right: 0;
        background-color: rgba(0, 200, 0, 0.7);
        padding: 4rpx 8rpx;
        border-top-left-radius: 8rpx;
        
        .info-text {
          color: #ffffff;
          font-size: 20rpx;
          font-weight: bold;
        }
      }
      
      .image-error {
        position: absolute;
        top: 0;
        right: 0;
        background-color: rgba(255, 0, 0, 0.7);
        padding: 4rpx 8rpx;
        border-bottom-left-radius: 8rpx;
        
        .error-text {
          color: #ffffff;
          font-size: 20rpx;
        }
      }
    }
  }
  
  .image-stats {
    padding: 10rpx 20rpx;
    border-top: 1rpx solid #f0f0f0;
    
    .stats-text {
      font-size: 24rpx;
      color: #666666;
    }
  }
  
  .popup-footer {
    padding: 20rpx 30rpx;
    border-top: 1rpx solid #f0f0f0;
    
    .confirm-btn {
      background-color: #ff6b6b;
      color: #ffffff;
      border-radius: 8rpx;
      font-size: 30rpx;
      height: 80rpx;
      line-height: 80rpx;
      
      &::after {
        border: none;
      }
    }
  }
}
</style> 